למה נכון לומר שיש בדיוק אפס גולשים און ליין?
איך בכל זאת יודעים כמה גולשים עכשיו באתר ואיך עושים את זה נכון
שאלה שמעניינת כל מנהל אתרים היא השאלה הנצחית: כמה אנשים גולשים לו עכשיו באתר.
ראשית יש להבין שתמיד התשובה היא אפס, ולא בגלל שהאתר לא כזה שווה, אלה בגלל מבנה הרשת. כאשר אתם גולשים לאתר כלשהו, הדפדפן שלכם שולח לשרת בקשה להביא לו עמוד כלשהו, לדוגמה index.html. השרת מקבל את הבקשה, מבצע את הבקשה בחלקי שניות, מחזיר לדפדפן את העמוד המבוקש וסוגר את החיבור איתו. לאחר שהשרת החזיר לדפדפן את הדף - הם לא מחוברים יותר ביחד.
בצעו ניסוי קטן. הוציאו עכשיו את כבל הרשת מהמחשב שלכם. אתם עדיין רואים את העמוד הזה? אתם כרגע באתר? איך אתם יכולים להיות כרגע מחוברים לאתר אם אתם אפילו לא מחוברים לאינטרנט?
מי נחשב לגולש כרגע באתר
הבקשה של הדפדפן לשרת להביא את הדף הזה הייתה לפני שניות בודדות. האם זה נחשב שברגע זה אתם גולשים באתר? קראתם את המשפט הזה ועברו עוד כמה שניות, אתם עדיין באתר? לשרת אין על זה שמץ של מושג, הרי ניתקתם את קבל הרשת שלכם. עלינו לקבוע מסגרת זמן שכל הבקשות בה יחשבו כגולשים באתר, וכל הבקשות הישנות יותר לא יחשבו כגולשים באתר.
לדוגמה אם מישהו שלח בקשה לעמוד כלשהו אתמול בערב ומאז לא שלח בקשות חדשות, האם ייחשב כגולש מחובר באתר? ואם זה היה לא אתמול בערב, אלה לפני 5 שעות? ו-3 שעות? שעה? אם משתמש עשה פעולה אחרונה כלשהי באתר לפני שעה (טען עמוד כלשהו) ומאז לא עשה יותר שום דבר, האם הוא נחשב למחובר כרגע?
מקובל לקבוע מסגרת זמן זו לשלוש דקות. משתמש שלא עשה שום דבר בשלוש דקות האחרונות באתר - כנראה כבר עזב. אתם יכולים לבחור מסגרת אחרת, אם המשתמשים קוראים עמודים באתר שלכם עם מילון או שיש לכם עמודים עם תוכן רב.
פורומים עם הרבה הודעות בעמוד לוקחים מסגרת של 10 דקות. כל מי שלא עשה שום פעולה (לא שלח שום בקשה לשרת) ב-10 דקות האחרונות כבר לא מחובר.
נרשום מתי הייתה הפעולה האחרונה של כל גולש
החישוב של כמות האנשים המחוברים מתבצעת לפי זמן הפעולה האחרון שלהם. כדי שנוכל לעשות את החישובים המתאימים - אנחנו חייבים לרשום את זמני הפעולה של כל גולש במסד וכאן יהיה לנו פיצול כלשהו. קיימים שני סוגי אתרים ולשניהם הקוד יהיה מעט שונה:
אתרים עם משתמשים רשומים, כמו פורומים, ואתרים בלי הרשמה, כמו האתר הזה למשל.
טבלת רישום באתרים בלי הרשמה
אנחנו צריכים להבדיל בין גולש לגולש, כי אין להם שמות שונים שנרשמו איתם. את ההבדלה נבצע באמצעות כתובת ה-IP, מזהה ייחודי של גולש ברשת שניתן לו על ידי ספק האינטנט בעת ההתחברות. שימו לב, ה-IP אינו קבוע לכל החיים ואצל ספקיות רבות הוא משתנה עם כל הפעלה מחדש של המודם.
ניצור טבלה שאליה נרשום את כל המשתמשים.
הטבלה תורכב בדיוק משני שדות. ה-ip והזמן שהתרחשה בו הפעולה האחרונה מכתובת ip זו.
CREATE TABLE `online` (
`ip` VARCHAR( 15 ) NOT NULL ,
`time` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
PRIMARY KEY ( `ip` )
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
`ip` VARCHAR( 15 ) NOT NULL ,
`time` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
PRIMARY KEY ( `ip` )
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
באתרים עם הרשמה
כיוון שלכל משתמש יש לנו שם משתמש משלו נכניס לטבלת המשתמשים users עוד עמודה נוספת ונרשום בה את זמן הפעולה האחרונה.
ALTER TABLE `userstable` ADD `time` TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
הקוד
הקוד לרישום הפעולה האחרונה בטבלה יראה כך:
$ip = mysql_real_escape_string($_SERVER['REMOTE_ADDR']);
mysql_query("INSERT INTO `online` (`ip`,`time`) VALUES ('$ip',CURRENT_TIMESTAMP)
ON DUPLICATE KEY UPDATE `time` = CURRENT_TIMESTAMP");
mysql_query("INSERT INTO `online` (`ip`,`time`) VALUES ('$ip',CURRENT_TIMESTAMP)
ON DUPLICATE KEY UPDATE `time` = CURRENT_TIMESTAMP");
תחילה נקבל את כתובת ה-ip הייחודית של הגולש למשתנה, אחר כך נכניס אותו לטבלה.
אם הוא כבר קיים בטבלה - לא נכניס אותו שוב, אלה רק נעדכן את זמן הפעולה האחרון שלו.
הפקודה on duplicate key -- update אומרת למסד שבמקרה וכבר קיימת רשומה עם ip כזה, יש לעשות עידכון במקום ההכנסה המחודשת.
לאתרים עם הרשמה הכל יותר פשוט. צריך רק לעדכן את זמן הפעולה האחרון של המשתמש
$user = mysql_real_escape_string(...);
mysql_query("UPDATE `userstable` SET `online` = CURRENT_TIMESTAMP
WHERE `user`='$user'");
mysql_query("UPDATE `userstable` SET `online` = CURRENT_TIMESTAMP
WHERE `user`='$user'");
איפה להפעיל את הקוד הזה
את הקוד הזה יש להפעיל בכל בקשה של המשתמש לשרת. כל ריענון, כל טעינה.
הדרך הכי טובה היא לרשום את הקוד הזה בקובץ counter.php ולעשות לו require_once כל טעינה. באתרים עם הרשמה את הקוד הזה אפשר להפעיל רק אחרי שהמשתמש הזדהה, אחרת אין לנו את מי לעדכן.
ספירת מחוברים
עכשיו יש לנו טבלה עם זמני הפעולה האחרונים של כל משתמש. נשאר רק לספור כמה מהם היו פעילים בשלוש דקות האחרונות ויהיה לנו מספר. הקוד לספירה יראה ככה:
$query = mysql_query("SELECT COUNT(*) FROM `online`
WHERE `time` > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 3 MINUTE)");
$online = mysql_result($query, 0, 0);
WHERE `time` > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 3 MINUTE)");
$online = mysql_result($query, 0, 0);
השאילתה סופרת את כמות השורות שבהם זמן הפעולה האחרונה גדול מ (עכשיו פחות 3 דקות).
זהו בעצם מספר הגולשים שכרגע נמצאים אונליין באתר. את המספר הזה אתם יכולים להציג איפהשו באתר, לצייר על כפתור יפה ולהראות בתחתית העמוד או סתם להשתמש בזה לצורכי סטטיסטיקה.
תגובות לכתבה:
כל הכבוד! אחלה מדריך :) רק תתקן את השגיאת כתיב ״לצורחי״
מדריך ממש נחמד, כל הכבוד!
מדריך מצוין וברור כמו כל התכנים באתר, כל הכבוד.
שתי הערות
מומלץ לאנדקס את TIME ופעם ביום למחוק מהטבלה רשומות שקטנות מעכשיו פחות קבוע זמן (3 דקות), אחרת תהיה לנו טבלה מאוד עמוסה לאחר מספר ימים/חודשים תלוי במספר הכניסות לאתר.
לא מספיק לספור כתובות אייפי מכיוון שכאשר המשתמשים שלך גולשים מבתי קפה או עסק וכדומה אז יש לך מספר רב של משתמשים עם אותה כתובת אייפי ולכן הספירה שלך לא נכונה.
לכן מומלץ לזהות משתמש לפי אייפי ועוגיה עם עירך חד חד ערכי ולא רק לפי אייפי.
נחמד מאוד!
לא ראיתי שיטה כזאת שמבוצעת ע"י מסד
שיטה נחמדה , באמת אבל יש דרך קיצור !!! דרך אגב אני כולה בת 12 ככה ש ... נחמד שאני יודת יותר ממשהו .. D :
אשמח אם תספרי על הדרך קיצור לכולנו וכל הכבוד.
יופי של מדריך.
לומד הרבה מאתרך, המשך כך.
תודה רבה לך המדריך מאוד עזר לי
המשך כך
מעניין אותי למה אתה עושה escape לאיפי, אם בלתי אפשרי לערוך אותו?
יפה מאוד :]
תמשיך להכין מדריכים מפורטים!
אני עושה escape גם לip
א. מתוך הרגל לעשות הברחה לכל כל הנתונים שאני מכניס למסד
ב. ליתר בטחון, אם השרת יחזיר במקום IPv6 ערך מוזר כלשהו. לא שקרה לי היי פעם, אבל אני עדיין לא מאמין לגמרי בדרך שבה השרתים nginx, apache מסתדרים עם ipV6
יפה!
אי אפשר לעשות פשוט כל עוד יש סיישן לסמן בטבלה
1 ואם אין סיישן לסמן 0 ואז זה יוריד ויעלה את מס' המחוברים לפי שאילתה?. כמובן שזה רק באתרים עם הרשמה
נכון לעשות דבר כזה?
איך אתה תדע אם "יש סשן או אין סשן יותר" ?
מה זאת אומרת הוא בודק בכל דף אם קיים הסיישן
ועוד דבר יש לי בעיה כזאת
arning: mysql_result() [function.mysql-result]: Unable to jump to row 0 on MySQL result index 10 in
שאלות לפורום.
הבעיה היא שאי אפשר לטפוס את הרגע שבו "הסשן נעלם". שהוא גם לא נעלם, אלה רק 25 דקות אחרי השימוש האחרון שלו. ואף אחד גם לא מודיע לך מתי היה השימוש האחרון שלו.
מה זאת אומרת סיישן לא נעלם ד"א אחלה אתר אלכס
דרך נוספת שמצאתי לבדוק אם מחובר או לא בשאילתה אחרת $query = mysql_query("SELECT `online` FROM `users` WHERE `id`='".$_GET['id']."'");
$online = mysql_fetch_assoc($query);
if($online['online']>(time()-320))
echo "מחובר";
else
echo "לא מחובר";
זה אותו דבר, רק שבמקום שהמסד יעשה את החישובים - PHP עושה אותם. ההבדל הוא שהמסד עושה את החישובים האלה מהר יותר ובפחות זיכרון.
אוקיי תודה אלכס
תודה!
תודה